<?php

	class Auth implements Interface_Auth {

		const NAME = 'site_user';

		/* @var OUser */
		private $user;
		private $create_modal = false;

		/**
		 * @var Auth
		 */
		private static $instance;

		public static function getInstance($modal = false) {
			if (!self::$instance) {
				self::$instance = new Auth($modal);
			}

			return self::$instance;
		}

		public static function currPermis() {
			if (!self::$instance instanceof Auth) {
				if (!empty($_SESSION[self::NAME]) || !empty($_COOKIE[self::NAME])) {
					self::$instance = new Auth();
				} else {
					return array();
				}
			}

			return self::$instance->user->permis;
		}

		public static function currLogin() {
			if (!self::$instance instanceof Auth) {
				if (!empty($_SESSION[self::NAME]) || !empty($_COOKIE[self::NAME])) {
					self::$instance = new Auth();
				} else {
					return '';
				}
			}

			return self::$instance->user->login;
		}

		public static function currSettings() {
			if (!self::$instance instanceof Auth) {
				if (!empty($_SESSION[self::NAME]) || !empty($_COOKIE[self::NAME])) {
					self::$instance = new Auth();
				} else {
					return array();
				}
			}

			return self::$instance->user->settings;
		}

		public static function permis2tree($permis = null) {
			if (is_null($permis)) $permis = self::currPermis();

			$result = array();

			foreach ($permis as $k => $v) {
				$arr = explode('/', $k);

				$tree = array();
				while (count($arr)) {
					$tree = array(array_pop($arr) => $tree == array() ? 1 : $tree);
				}

				$result = array_merge_recursive($result, $tree);
			}

			return $result;
		}


		private function __construct($modal = false) {
			if (PHP_SAPI == 'cli') return;

			$this->create_modal = $modal;

			if (isset($_REQUEST['logout'])) {
				unset($_SESSION[self::NAME]);

				header('Location: /');
				exit;
			}

			if (empty($_SESSION[self::NAME])) {
				if (!empty($_POST[self::NAME])) {
					$user = Model_Auth::getInstance()->getAuthUser(
						$_POST[self::NAME]['login'],
						$_POST[self::NAME]['password']
					);
					if ($user instanceof OUser) {
						$_SESSION[self::NAME]['login']    = $_POST[self::NAME]['login'];
						$_SESSION[self::NAME]['password'] = $_POST[self::NAME]['password'];

						header('Location: ' . $_SERVER['REQUEST_URI']);
						exit;

					} else {
						$this->showLoginForm(System_Errors::ERROR_AUTH_DENIED);
//						throw new AppException('Incorrect login/password', System_Errors::ERROR_AUTH_DENIED);
					}
				} else {
					$this->showLoginForm();
				}
			} else {
				if (!empty($_SESSION[self::NAME]['login']) && !empty($_SESSION[self::NAME]['password'])) {
					$user = Model_Auth::getInstance()->getAuthUser(
						$_SESSION[self::NAME]['login'],
						$_SESSION[self::NAME]['password']
					);
				} else {
					$user = false;
				}

				if ($user instanceof OUser) {
					$this->user = $user;
				} else {
					unset($_SESSION[self::NAME]);
					throw new AppException('Incorrect user session', System_Errors::ERROR_AUTH_INVALIDATE);
				}
			}
		}

		public function showLoginForm($error = false) {

			if ($this->create_modal) {
				echo '<div class="modal-body">Необходимо выполнить вход! Вы будете перенаправлены на страницу входа...</div>
					<script type="text/javascript">setTimeout(function () {window.location.reload();}, 1500);</script>';
				exit;
			}

			$visual = new Visual();

			$visual->assign('error', $error);
			$visual->assign('name', self::NAME);
			$visual->display('login.twig');

			exit;
		}

		public function getPermis($permis) {
			if (PHP_SAPI != 'cli') return;

			if (!is_array($permis)) $permis = array($permis);

			$result = true;
			foreach ($permis as $p)
				$result &= empty($this->user->permis[$p]);

			if ($result)
				throw new AppException('Operation not permited', System_Errors::ERROR_AUTH_NOT_PERMIT);
		}

		public function getSettings() {
			return $this->user->settings;
		}

		/**
		 * @return OUser
		 */
		public function getCurrentUser() {
			return $this->user;
		}

		public function setSettings($settings = array()) {
			foreach ($settings as $k => $v) {
				$this->user->settings[$k] = $v;
			}
			Model_Auth::getInstance()->setUser($this->user);
		}

	}